home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / unix / pdmake / part01 next >
Encoding:
Internet Message Format  |  1990-06-04  |  51.5 KB

  1. Path: wuarchive!swbatl!texbell!cs.utexas.edu!usc!elroy.jpl.nasa.gov!ames!xanth!cs.odu.edu!Amiga-Request
  2. From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v90i177: pdmake - maintain program groups, Part01/02
  5. Message-ID: <12706@xanth.cs.odu.edu>
  6. Date: 4 Jun 90 00:20:55 GMT
  7. Sender: tadguy@cs.odu.edu
  8. Reply-To: huver@amgraf.uucp
  9. Lines: 1999
  10. Approved: tadguy@cs.odu.edu (Tad Guy)
  11. X-Mail-Submissions-To: Amiga@cs.odu.edu
  12. X-Post-Discussions-To: comp.sys.amiga
  13.  
  14. Submitted-by: huver@amgraf.uucp
  15. Posting-number: Volume 90, Issue 177
  16. Archive-name: unix/pdmake/part01
  17.  
  18. I took the PDmake that Steve Walton ported to Amiga, and enhanced it a bit.
  19. Many attempts were made to contact Steve, but all failed (no mail bounce,
  20. absolutely nothing came back from him).  So here it is, the complete thing.
  21. Note there was no version number at all in the PDmake distribution.  If this
  22. is your first time seeing such buzzword as "PDmake", you should read the
  23. fles README, README.amiga first.
  24.  
  25. #!/bin/sh
  26. # This is a shell archive.  Remove anything before this line, then unpack
  27. # it by saving it into a file and typing "sh file".  To overwrite existing
  28. # files, type "sh file -c".  You can also feed this as standard input via
  29. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  30. # will see the following message at the end:
  31. #        "End of archive 1 (of 2)."
  32. # Contents:  Changes.new README README.amiga an assign_macro.c check.c
  33. #   h.h input.c macro.c main.c make.n makefile reader.c
  34. # Wrapped by tadguy@xanth on Sun Jun  3 20:20:41 1990
  35. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  36. if test -f 'Changes.new' -a "${1}" != "-c" ; then 
  37.   echo shar: Will not clobber existing file \"'Changes.new'\"
  38. else
  39. echo shar: Extracting \"'Changes.new'\" \(3328 characters\)
  40. sed "s/^X//" >'Changes.new' <<'END_OF_FILE'
  41. XApril 18, 1990
  42. X--huver hu  ...!uunet!amgraf!huver  -or-  huver%amgraf@uunet.uu.net
  43. X
  44. X
  45. XI took the PDmake that Steve Walton ported to Amiga, and enhanced it a bit.
  46. XMany attempts were made to contact Steve, but all failed (no mail bounce,
  47. Xabsolutely nothing came back from him).  So here it is, the complete thing.
  48. XNote there was no version number at all in the PDmake distribution.  If this
  49. Xis your first time seeing such buzzword as "PDmake", you should read the
  50. Xfles README, README.amiga first, and then come back here.
  51. X
  52. XMy changes include:
  53. X
  54. X  * Define suffixes .asm, .a, .s to all be assembler source files.
  55. X
  56. X  * Added macros LD, LDFLAGS and LDLIBS so a linker can be invoked.  For
  57. X    Manx compiler system:
  58. X
  59. X    LD = ln        # linker program name
  60. X    LDFLAGS =
  61. X    LDLIBS = -lc    # link with c.lib library
  62. X
  63. X  * Add internal suffix .~ to generate an executable from a found source
  64. X    file.  The match order looks for assembler suffixes before .c suffix.
  65. X
  66. X  * Run without a makefile present; i.e. a command line:
  67. X
  68. X    make "CCFLGS=+L" foo
  69. X
  70. X    runs the following actions (with Manx 3.6a):
  71. X
  72. X    cc +L foo.c
  73. X    ln -o foo foo.o -lc
  74. X
  75. X    if foo.c is found in the current directory (note: the "-o" in linker
  76. X    command above is not LDFLAGS, it comes from built-in rules; see rules.c).
  77. X    This type of operation works only as indicated above (one source file
  78. X    that is self-contained).  Not a big deal, but it lets you get your simple
  79. X    stand-alone tester made without overworking your fingers.
  80. X
  81. X  * Instead of stopping at a target that Make doesn't know how to make, it
  82. X    now issues an error message and continues on.  So:
  83. X
  84. X    make "CCFLAGS=+L" foo bar
  85. X
  86. X    make: Don't know how to make foo.
  87. X
  88. X    cc +L bar.c
  89. X    ln -o bar bar.o -lc
  90. X
  91. X    would still make "bar" in the event that no foo.* is found.
  92. X
  93. X  * Corrected errors in handling '#' comment marker in the makefile.  Such
  94. X    comment mark can appear anywhere, from it to the first end-of-line is
  95. X    all skipped.  Likewise, there was problem in the backslash continuation
  96. X    handling.  The Makefile included with this distribution contains comment
  97. X    lines placed on purpose, to illustrate what I mean here.
  98. X
  99. X  * Added "-?" option to list all options.
  100. X
  101. XOtherwise, the original features Steve Walton put in are left intact.
  102. XAs far as I can tell, nothing should break under Manx 5.0 compiler.
  103. X
  104. X
  105. XMissing "feaures":
  106. X
  107. X  1. This Make definitely has no such concept as "being run from WB".
  108. X
  109. X  2. It cannot call itself to travel down a directory tree (no MAKE macro
  110. X     and certainly no MFLAGS environmental variable).
  111. X
  112. X  3. It does not support object libraries.
  113. X
  114. XNotes to those of you who do not use Manx compiler:
  115. X
  116. X  This make was written to use MANX's fexec() call to invoke commands (and
  117. X  get their exit status back).  I have no idea how other compilers do this.
  118. X
  119. X  To take advantage of the source-to-executable action, you need to have
  120. X  at least LD macro defined in "rules.c" (toward the end) -- having LDFLAGS
  121. X  and LDLIBS defined wouldn't hurt, but may prove to be inconvenient.  Edit
  122. X  rules.c, go to the end and back up to where "#ifdef amiga" is at.  Look for
  123. X  things that I did (they are marked by comments with "--hu"), use them as
  124. X  templates to set up command rules for make to call your compiler/linker.
  125. X
  126. X
  127. XYour comments are welcome, but don't expect me to be your Amiga PDmake
  128. Xsupport, though.
  129. END_OF_FILE
  130. if test 3328 -ne `wc -c <'Changes.new'`; then
  131.     echo shar: \"'Changes.new'\" unpacked with wrong size!
  132. fi
  133. # end of 'Changes.new'
  134. fi
  135. if test -f 'README' -a "${1}" != "-c" ; then 
  136.   echo shar: Will not clobber existing file \"'README'\"
  137. else
  138. echo shar: Extracting \"'README'\" \(1803 characters\)
  139. sed "s/^X//" >'README' <<'END_OF_FILE'
  140. XFollowing is a repost of the public domain 'make' that I posted
  141. Xto net.sources a couple of months ago.  I have fixed a few bugs, and
  142. Xadded some more features, and the resulting changes amounted to
  143. Xabout as much text as the whole program (hence the repost).
  144. X
  145. XFor those that missed the net.sources posting, this is a public domain
  146. Xre-implementation of the UNIX make program.  There is no manual included;
  147. Xfor documentation, refer to a UNIX manual, or the source.
  148. X
  149. XHere is a list of the changes made:
  150. X
  151. Xi)    If '-' (ignore) or '@' (silent) where used at the start
  152. X    of a command, their effect was not turned off for the following
  153. X    commands.
  154. Xii)    A special target (.SUFFIXES, .PRECIOUS) or a rule (.c.o, .a.o),
  155. X    if first in the file would be taken as the default target.
  156. X    This resulted in error messages like "Don't know how to
  157. X    make .c", because things like .SUFFIXES were being made.
  158. X    This was further complicated by ---
  159. Xiii)    Special target lines with no dependents (ie. .SUFFIXES:\n)
  160. X    were not clearing out the existing dependents like
  161. X    they should.
  162. Xiv)    Default rules could not be redefined because of the error
  163. X    checking for commands being defined twice.  Now you are
  164. X    allowed to define a target beinging with '.', having
  165. X    no dependents with commands.
  166. Xv)    The -q option didn't do the time comparison correctly,
  167. X    or clear the variable used to keep track of this.  Thus
  168. X    it didn't work very well.
  169. Xvi)    The syntax ${..} for macro's supported by UNIX make was
  170. X    not supported.
  171. Xvii)    There wuz a couple of spelling errors.
  172. Xviii)    When make checked for implicit rules on targets without
  173. X    a suffix, there were problems.  (Note: The ~ feature of
  174. X    UNIX make wasn't and still isn't supported)
  175. Xix)    The -n option did not print @ lines like it was supposed to.
  176. Xx)    :: added.  (See UNIX manual)
  177. Xxi)    $? added.  (see UNIX manual)
  178. END_OF_FILE
  179. if test 1803 -ne `wc -c <'README'`; then
  180.     echo shar: \"'README'\" unpacked with wrong size!
  181. fi
  182. # end of 'README'
  183. fi
  184. if test -f 'README.amiga' -a "${1}" != "-c" ; then 
  185.   echo shar: Will not clobber existing file \"'README.amiga'\"
  186. else
  187. echo shar: Extracting \"'README.amiga'\" \(4397 characters\)
  188. sed "s/^X//" >'README.amiga' <<'END_OF_FILE'
  189. XThis program is the public domain Make program which appeared on
  190. Xmod.sources, Volume 7, number 91.  I have ported it to the Amiga under
  191. XManx Aztec C version 3.40a.  This short document assumes you know
  192. XMake, and simply points out the Amiga specific features of the
  193. Xprogram.  The supported switches are listed in the comment block at
  194. Xthe beginning of module main.c.  I offer no apologies for the fact that
  195. XI ran the code through "indent -i4 -nfc1" on the 4.3BSD system at work
  196. Xbefore I started working on it.
  197. X   The program has been compiled under Manx Aztec C Version 3.40.
  198. XIt uses Manx's fexecv() function to execute commands and get
  199. Xtheir return value, and the Manx dos_packet() function to send an
  200. XAmigaDOS packet to the file system for touch'ing purposes.  Lattice
  201. Xrecompilers need to change these (at least).  Peculiar features
  202. Xof the Amiga version are:
  203. X
  204. X(1) The Amiga-specific sections of the code are #ifdef'd on the symbol
  205. X    amiga (note the lower case).  I endorse Fred Fish's effort to
  206. X    have system and compiler-supplied #define's in lower case to
  207. X    ensure no collisions with user-supplied ones.
  208. X(2) The file rules.c, routine makerules(), contains the definitions of
  209. X    the default built-in rules. For the Amiga, these are equivalent to
  210. X    the Makefile:
  211. X
  212. X    CC = cc
  213. X    CFLAGS =
  214. X    AS = as
  215. X    AFLAGS =
  216. X
  217. X    .c.o:
  218. X        $(CC) $(CFLAGS) $<
  219. X    .s.o:
  220. X        $(AS) $(AFLAGS) -o $@ $<
  221. X
  222. X    (indented for clarity only).  Thus, one could conceivably do:
  223. X    make CC=lc CFLAGS= AS=asm
  224. X    to run this make under Lattice C.
  225. X(3) If the file S:builtins.make exists, its contents are read in
  226. X    instead of the built-in rules defined in makerules().  Thus, you
  227. X    can use different default rules on different disks and change
  228. X    the default rules without recompiling make.
  229. X(4) A Control-D typed during execution of a command by make will cause
  230. X    an abort with exit status 1 AFTER the completion of that command.
  231. X    Control-C is an immediate abort, as you might expect.
  232. X(5) Not really Amiga specific, but worth mentioning, is that characters
  233. X    special both to the local operating system (such as : in AmigaDOS) and
  234. X    to make may be used in the makefile by preceding them with \
  235. X    to temporarily override their special meaning.  For example, to tell
  236. X    make that RAM:foo depends on AC:foo.c, write:
  237. X
  238. X    RAM\:foo : AC\:foo.c
  239. X
  240. X(6) The Aztec fexecv() function, which is used by make to execute its
  241. X    commands, only works on programs in directories stored along the
  242. X    AmigaDOS PATH, so make sure your PATH includes the appropriate
  243. X    directories.
  244. X
  245. X    Finally, I added one new feature in the non-machine-specific code:
  246. Xthe name of the makefile can be a single dash "-", in which case a
  247. Xmakefile is read from the standard input.
  248. X    About the only feature of "real" make missing here is the
  249. Xsemicolon construct which allows a pair of lines such as the .c.o:
  250. Xrule and command above to be written as one line, viz:
  251. X    .c.o: ; $(CC) $(CFLAGS) $<
  252. X
  253. XEnjoy!    Bug reports in the Amiga-specific stuff should be directed to
  254. Xme;  others should go to caret@fairlight.OZ, the author of the rest of it.
  255. XBy the way, this code is superior to the Manx-supplied make--more switches
  256. Xand a better parser;  in fact, this make will handle the Makefile for
  257. XMicroGnuEmacs while Manx make chokes on the ln command.
  258. X
  259. X                Steve Walton
  260. X                ametek!walton@csvax.caltech.edu (ARPA)
  261. X                WALTON@CALTECH (BITNET)
  262. X                ...!ucbvax!sun!megatest!ametek!walton
  263. X
  264. XSome notes by Olaf Seibert, KosmoSoft:
  265. X
  266. XI adapted this version of make to PDC, and enhanced it a little. In
  267. Xparticular, if a line end with a backslash, the following newline and
  268. Xleading white space of the next line are now ignored. Previously, the
  269. Xnewline was merely turned into a space. Also, comparison of filenames now
  270. Xis case-insignificant. Makefiles need not be internally consistent in the
  271. Xcase of filenames. Also, the builtin rules are slightly different, for use
  272. Xwith PDC.
  273. X
  274. X    CC = ccx -c
  275. X    CFLAGS =
  276. X    AS = ccx -c
  277. X    AFLAGS =
  278. X
  279. X    .c.o:
  280. X        $(CC) $(CFLAGS) $<
  281. X    .s.o:
  282. X        $(AS) $(AFLAGS) $<
  283. X
  284. X                /*OIS*0.80*/
  285. X
  286. XI took out the \: feature, which worked only in target names, and not in
  287. Xprerequisite files. Instead, I added a more rational interpretation of
  288. Xcolons. There is now at most one colon possible in a target name, which may
  289. Xnot contain any spaces.
  290. X
  291. XI incorporared a few bug fixes relating to $< and $*, from the minix newsgroup.
  292. XI added a new feature: the .PATH special target. See manual.
  293. X
  294. END_OF_FILE
  295. if test 4397 -ne `wc -c <'README.amiga'`; then
  296.     echo shar: \"'README.amiga'\" unpacked with wrong size!
  297. fi
  298. # end of 'README.amiga'
  299. fi
  300. if test -f 'an' -a "${1}" != "-c" ; then 
  301.   echo shar: Will not clobber existing file \"'an'\"
  302. else
  303. echo shar: Extracting \"'an'\" \(2210 characters\)
  304. sed "s/^X//" >'an' <<'END_OF_FILE'
  305. X.*
  306. X.*    Macro package for NRO in KosmoSoft version
  307. X.*
  308. X.nr h 5      @" header indent
  309. X.nr i 10     @" normal text indent
  310. X.nr s @ni-@nh     @" section heading indent (to the LEFT)
  311. X.*
  312. X.de TH
  313. X.in @nh;.rm 80-@nh;.he |$0($1)|$2|$0($1)|
  314. X.fo |$3|-#-|$4|
  315. X.in @ni;.rm 80-@ni
  316. X.ta +0 +5
  317. X.en
  318. X.*  Paragraph
  319. X.de PP
  320. X.sp 1;.ne 2;.ti +5
  321. X.en
  322. X.*  Bulleted Paragraph. Needs .RE after last para.
  323. X.*  Must be last on line. Relies on first tab stop.
  324. X.de BP
  325. X.br;.in @ni+5;.ti -3;o@t@@
  326. X.en
  327. X.*  Section Heading
  328. X.de SH
  329. X.sp 1;.ne 3;.ti -@@ns;.bo "$0 $1 $2 $3 $4 $6 $6 $7 $8 $9
  330. X.br
  331. X.en
  332. X.*  SubSection
  333. X.de SS
  334. X.br;.ne 2;.ti -@@ns+1/2;$0 $1 $2 $3 $4 $5 $6 $7 $8 $9
  335. X.br
  336. X.en
  337. X.*  Relative indent Start
  338. X.de RS
  339. X.in +0$0
  340. X.en
  341. X.*  Relative indent End
  342. X.de RE
  343. X.in @ni
  344. X.en
  345. X.*  Italics
  346. X.de I
  347. X.it 1
  348. X$0 $1 $2 $3 $4 $5 $6 $7 $8 $9
  349. X.en
  350. X.*  Bold
  351. X.de B
  352. X.bo 1
  353. X$0 $1 $2 $3 $4 $5 $6 $7 $8 $9
  354. X.en
  355. X.*  Underline
  356. X.de U
  357. X.ul 1
  358. X$0 $1 $2 $3 $4 $5 $6 $7 $8 $9
  359. X.en
  360. X.*  UC
  361. X.de UC
  362. X.*  Empty
  363. X.en
  364. X.*  Italics and Roman
  365. X.de IR
  366. X.if !''$0' .it "$0
  367. X.if !''$1' $1
  368. X.if !''$2' .it "$2
  369. X.if !''$3' $3
  370. X.if !''$4' .it "$4
  371. X.if !''$5' $5
  372. X.if !''$6' .it "$6
  373. X.if !''$7' $7
  374. X.if !''$8' .it "$8
  375. X.if !''$9' $9
  376. X.en
  377. X.*  Roman and Italic
  378. X.de RI
  379. X.if !''$0' $0
  380. X.if !''$1' .it "$1
  381. X.if !''$2' $2
  382. X.if !''$3' .it "$3
  383. X.if !''$4' $4
  384. X.if !''$5' .it "$5
  385. X.if !''$6' $6
  386. X.if !''$7' .it "$7
  387. X.if !''$8' $8
  388. X.if !''$9' .it "$9
  389. X.en
  390. X.*  Bold and Roman
  391. X.de BR
  392. X.if !''$0' .bo "$0
  393. X.if !''$1' $1
  394. X.if !''$2' .bo "$2
  395. X.if !''$3' $3
  396. X.if !''$4' .bo "$4
  397. X.if !''$5' $5
  398. X.if !''$6' .bo "$6
  399. X.if !''$7' $7
  400. X.if !''$8' .bo "$8
  401. X.if !''$9' $9
  402. X.en
  403. X.*  Bold and Italic
  404. X.de BI
  405. X.if !''$0' .bo "$0
  406. X.if !''$1' .it "$1
  407. X.if !''$2' .bo "$2
  408. X.if !''$3' .it "$3
  409. X.if !''$4' .bo "$4
  410. X.if !''$5' .it "$5
  411. X.if !''$6' .bo "$6
  412. X.if !''$7' .it "$7
  413. X.if !''$8' .bo "$8
  414. X.if !''$9' .it "$9
  415. X.en
  416. X.*  Italic and Bold
  417. X.de IB
  418. X.if !''$0' .it "$0
  419. X.if !''$1' .bo "$1
  420. X.if !''$2' .it "$2
  421. X.if !''$3' .bo "$3
  422. X.if !''$4' .it "$4
  423. X.if !''$5' .bo "$5
  424. X.if !''$6' .it "$6
  425. X.if !''$7' .bo "$7
  426. X.if !''$8' .it "$8
  427. X.if !''$9' .bo "$9
  428. X.en
  429. X.*  Italic and Roman
  430. X.de IR
  431. X.if !''$0' .it "$0
  432. X.if !''$1' $1
  433. X.if !''$2' .it "$2
  434. X.if !''$3' $3
  435. X.if !''$4' .it "$4
  436. X.if !''$5' $5
  437. X.if !''$6' .it "$6
  438. X.if !''$7' $7
  439. X.if !''$8' .it "$8
  440. X.if !''$9' $9
  441. X.en
  442. X.*  SMall, do nothing
  443. X.de SM
  444. X$0 $1 $2 $3 $4 $5 $6 $7 $8 $9
  445. X.en
  446. END_OF_FILE
  447. if test 2210 -ne `wc -c <'an'`; then
  448.     echo shar: \"'an'\" unpacked with wrong size!
  449. fi
  450. # end of 'an'
  451. fi
  452. if test -f 'assign_macro.c' -a "${1}" != "-c" ; then 
  453.   echo shar: Will not clobber existing file \"'assign_macro.c'\"
  454. else
  455. echo shar: Extracting \"'assign_macro.c'\" \(1157 characters\)
  456. sed "s/^X//" >'assign_macro.c' <<'END_OF_FILE'
  457. X#include <stdio.h>
  458. X#include <string.h>
  459. X#include <ctype.h>
  460. X
  461. X/* 02/12/90 -- hu:
  462. X * New utility function for make to process a macro assignment string.
  463. X * Uses standard C string/ctype functions so it is not machine dependent.
  464. X * Called by input() and main().
  465. X*/
  466. Xvoid
  467. Xassign_macro (s)
  468. Xchar *s;    /* s must be pre-checked for the presence of '=' */
  469. X{
  470. X    char *name, *val;
  471. X    register char *p, *q;
  472. X    char svp, svq;
  473. X    int  use_empty = 0;
  474. X
  475. X    /* bypass leading space */
  476. X    while (isspace (*s)) s++;
  477. X    name = s;
  478. X
  479. X    /* find the = char */
  480. X    p = strchr (s, '=');
  481. X    if (p == name) return;
  482. X    val = p + 1;
  483. X
  484. X    if (*(p-1) == '\\') {
  485. X      if ((p - 1) == name) return;
  486. X      p--;
  487. X    }
  488. X    p--;
  489. X    while (isspace(*p)) p--;
  490. X    p++;
  491. X    svp = *p;
  492. X    *p = '\0';
  493. X
  494. X    /* now check the value part, we just need to see if null string */
  495. X    q = val;
  496. X    while (*q != '\0'  &&  isspace(*q)) q++;
  497. X    if (*q == '\0') use_empty = 1;
  498. X    else {
  499. X      val = q;
  500. X      q = val + strlen(val) - 1;
  501. X      if (isspace(*q)) while (isspace(*q)) q--;
  502. X      q++;
  503. X      svq = *q;
  504. X      *q = '\0';
  505. X    }
  506. X
  507. X    if (use_empty) setmacro (name, " ");
  508. X    else setmacro (name, val);
  509. X
  510. X    /* restore original chars that we replaced with null */
  511. X    *p = svp;
  512. X    if (use_empty == 0) *q = svq;
  513. X}
  514. END_OF_FILE
  515. if test 1157 -ne `wc -c <'assign_macro.c'`; then
  516.     echo shar: \"'assign_macro.c'\" unpacked with wrong size!
  517. fi
  518. # end of 'assign_macro.c'
  519. fi
  520. if test -f 'check.c' -a "${1}" != "-c" ; then 
  521.   echo shar: Will not clobber existing file \"'check.c'\"
  522. else
  523. echo shar: Extracting \"'check.c'\" \(2152 characters\)
  524. sed "s/^X//" >'check.c' <<'END_OF_FILE'
  525. X/*
  526. X *    Check structures for make.
  527. X */
  528. X
  529. X#include <stdio.h>
  530. X#include "h.h"
  531. X
  532. X
  533. X/*
  534. X *    Prints out the structures as defined in memory.  Good for check
  535. X *    that you make file does what you want (and for debugging make).
  536. X */
  537. Xvoid
  538. Xprt()
  539. X{
  540. X    register struct name *np;
  541. X    register struct depend *dp;
  542. X    register struct line *lp;
  543. X    register struct cmd *cp;
  544. X    register struct macro *mp;
  545. X
  546. X
  547. X    for (mp = macrohead; mp; mp = mp->m_next)
  548. X    fprintf(stderr, "%s = %s\n", mp->m_name, mp->m_val);
  549. X
  550. X    fputc('\n', stderr);
  551. X
  552. X    for (np = namehead.n_next; np; np = np->n_next) {
  553. X    if (np->n_flag & N_DOUBLE)
  554. X        fprintf(stderr, "%s::\n", np->n_name);
  555. X    else
  556. X        fprintf(stderr, "%s:\n", np->n_name);
  557. X    if (np == firstname)
  558. X        fprintf(stderr, "(MAIN NAME)\n");
  559. X    for (lp = np->n_line; lp; lp = lp->l_next) {
  560. X        fputc(':', stderr);
  561. X        for (dp = lp->l_dep; dp; dp = dp->d_next)
  562. X        fprintf(stderr, " %s", dp->d_name->n_name);
  563. X        fputc('\n', stderr);
  564. X
  565. X        for (cp = lp->l_cmd; cp; cp = cp->c_next)
  566. X#ifdef os9
  567. X        fprintf(stderr, "-   %s\n", cp->c_cmd);
  568. X#else
  569. X        fprintf(stderr, "-\t%s\n", cp->c_cmd);
  570. X#endif
  571. X        fputc('\n', stderr);
  572. X    }
  573. X    fputc('\n', stderr);
  574. X    }
  575. X}
  576. X
  577. X
  578. X/*
  579. X *    Recursive routine that does the actual checking.
  580. X */
  581. Xvoid
  582. Xcheck(np)
  583. X    struct name    *np;
  584. X{
  585. X    register struct depend *dp;
  586. X    register struct line *lp;
  587. X
  588. X
  589. X    if (np->n_flag & N_MARK)
  590. X    fatal("Circular dependency from %s", np->n_name);
  591. X
  592. X    np->n_flag |= N_MARK;
  593. X
  594. X    for (lp = np->n_line; lp; lp = lp->l_next)
  595. X    for (dp = lp->l_dep; dp; dp = dp->d_next)
  596. X        check(dp->d_name);
  597. X
  598. X    np->n_flag &= ~N_MARK;
  599. X}
  600. X
  601. X
  602. X/*
  603. X *    Look for circular dependancies.
  604. X *    ie.
  605. X *        a: b
  606. X *        b: a
  607. X *    is a circular dep
  608. X */
  609. Xvoid
  610. Xcirch()
  611. X{
  612. X    register struct name *np;
  613. X
  614. X
  615. X    for (np = namehead.n_next; np; np = np->n_next)
  616. X    check(np);
  617. X}
  618. X
  619. X
  620. X/*
  621. X *    Check the target .PRECIOUS, and mark its dependentd as precious
  622. X */
  623. Xvoid
  624. Xprecious()
  625. X{
  626. X    register struct depend *dp;
  627. X    register struct line *lp;
  628. X    register struct name *np;
  629. X
  630. X
  631. X    if (!((np = newname(".PRECIOUS"))->n_flag & N_TARG))
  632. X    return;
  633. X
  634. X    for (lp = np->n_line; lp; lp = lp->l_next)
  635. X    for (dp = lp->l_dep; dp; dp = dp->d_next)
  636. X        dp->d_name->n_flag |= N_PREC;
  637. X}
  638. END_OF_FILE
  639. if test 2152 -ne `wc -c <'check.c'`; then
  640.     echo shar: \"'check.c'\" unpacked with wrong size!
  641. fi
  642. # end of 'check.c'
  643. fi
  644. if test -f 'h.h' -a "${1}" != "-c" ; then 
  645.   echo shar: Will not clobber existing file \"'h.h'\"
  646. else
  647. echo shar: Extracting \"'h.h'\" \(2546 characters\)
  648. sed "s/^X//" >'h.h' <<'END_OF_FILE'
  649. X/*
  650. X *    Include header for make
  651. X */
  652. X
  653. X
  654. X#ifndef uchar
  655. X#ifdef os9
  656. X#define uchar        char
  657. X#define void        int
  658. X#define fputc        putc
  659. X#else
  660. X#define uchar        unsigned char
  661. X#endif
  662. X#endif
  663. X
  664. X#define bool        uchar
  665. X#define time_t        long
  666. X#define TRUE        (1)
  667. X#define FALSE        (0)
  668. X#define max(a,b)    ((a)>(b)?(a):(b))
  669. X
  670. X#define DEFN1        "makefile"      /* Default names  */
  671. X#ifdef unix
  672. X#define DEFN2        "Makefile"
  673. X#endif
  674. X#ifdef eon
  675. X#define DEFN2        "Makefile"
  676. X#endif
  677. X
  678. X#ifdef amiga
  679. X#define strcmp        stricmp
  680. X#endif
  681. X
  682. X/* os9 is case insensitive */
  683. X
  684. X#define LZ        (1024)    /* Line size  */
  685. X
  686. X
  687. X
  688. X/*
  689. X *    A name.  This represents a file, either to be made, or existant
  690. X */
  691. X
  692. Xstruct name {
  693. X    struct name    *n_next;    /* Next in the list of names */
  694. X    char       *n_name;    /* Called */
  695. X    struct line    *n_line;    /* Dependencies */
  696. X    time_t        n_time;    /* Modify time of this name */
  697. X    uchar        n_flag;    /* Info about the name */
  698. X};
  699. X
  700. X#define N_MARK        0x01    /* For cycle check */
  701. X#define N_DONE        0x02    /* Name looked at */
  702. X#define N_TARG        0x04    /* Name is a target */
  703. X#define N_PREC        0x08    /* Target is precious */
  704. X#define N_DOUBLE    0x10    /* Double colon target */
  705. X
  706. X/*
  707. X *    Definition of a target line.
  708. X */
  709. Xstruct line {
  710. X    struct line    *l_next;    /* Next line (for ::) */
  711. X    struct depend  *l_dep;    /* Dependents for this line */
  712. X    struct cmd       *l_cmd;    /* Commands for this line */
  713. X};
  714. X
  715. X
  716. X/*
  717. X *    List of dependents for a line
  718. X */
  719. Xstruct depend {
  720. X    struct depend  *d_next;    /* Next dependent */
  721. X    struct name    *d_name;    /* Name of dependent */
  722. X};
  723. X
  724. X
  725. X/*
  726. X *    Commands for a line
  727. X */
  728. Xstruct cmd {
  729. X    struct cmd       *c_next;    /* Next command line */
  730. X    char       *c_cmd;    /* Command line */
  731. X};
  732. X
  733. X
  734. X/*
  735. X *    Macro storage
  736. X */
  737. Xstruct macro {
  738. X    struct macro   *m_next;    /* Next variable */
  739. X    char       *m_name;    /* Called ... */
  740. X    char       *m_val;    /* Its value */
  741. X    uchar        m_flag;    /* Infinite loop check */
  742. X};
  743. X
  744. Xextern char    *myname;
  745. Xextern struct name namehead;
  746. Xextern struct macro *macrohead;
  747. Xextern struct name *firstname;
  748. Xextern bool    silent;
  749. Xextern bool    ignore;
  750. Xextern bool    rules;
  751. Xextern bool    dotouch;
  752. Xextern bool    quest;
  753. Xextern bool    domake;
  754. Xextern char    str1[];
  755. Xextern char    str2[];
  756. Xextern int    lineno;
  757. X
  758. Xchar           *fgets();
  759. Xchar           *index();
  760. Xchar           *rindex();
  761. Xchar           *malloc();
  762. Xextern int    errno;
  763. X
  764. Xchar           *getmacro();
  765. Xstruct macro   *setmacro();
  766. Xvoid        input();
  767. Xvoid        error();
  768. Xvoid        fatal();
  769. Xint        make();
  770. Xstruct name    *newname();
  771. Xstruct depend  *newdep();
  772. Xstruct cmd     *newcmd();
  773. Xvoid        newline();
  774. Xchar           *suffix();
  775. Xvoid        touch();
  776. Xvoid        makerules();
  777. Xchar           *gettok();
  778. Xvoid        precious();
  779. END_OF_FILE
  780. if test 2546 -ne `wc -c <'h.h'`; then
  781.     echo shar: \"'h.h'\" unpacked with wrong size!
  782. fi
  783. # end of 'h.h'
  784. fi
  785. if test -f 'input.c' -a "${1}" != "-c" ; then 
  786.   echo shar: Will not clobber existing file \"'input.c'\"
  787. else
  788. echo shar: Extracting \"'input.c'\" \(7073 characters\)
  789. sed "s/^X//" >'input.c' <<'END_OF_FILE'
  790. X/*
  791. X *    Parse a makefile
  792. X */
  793. X
  794. X
  795. X#include <stdio.h>
  796. X#include <ctype.h>
  797. X#include "h.h"
  798. X
  799. X
  800. Xstruct name    namehead;
  801. Xstruct name    *firstname;
  802. X
  803. Xchar        str1[LZ];    /* General store  */
  804. Xchar        str2[LZ];
  805. X
  806. X
  807. X/*
  808. X *    Intern a name.    Return a pointer to the name struct
  809. X */
  810. Xstruct name    *
  811. Xnewname(name)
  812. X    char       *name;
  813. X{
  814. X    register struct name *rp;
  815. X    register struct name *rrp;
  816. X    register char  *cp;
  817. X
  818. X
  819. X    for
  820. X    (
  821. X     rp = namehead.n_next, rrp = &namehead;
  822. X     rp;
  823. X     rp = rp->n_next, rrp = rrp->n_next
  824. X    )
  825. X    if (strcmp(name, rp->n_name) == 0)
  826. X        return rp;
  827. X
  828. X    if ((rp = (struct name *) malloc(sizeof(struct name)))
  829. X    == (struct name *) 0)
  830. X    fatal("No memory for name");
  831. X    rrp->n_next = rp;
  832. X    rp->n_next = (struct name *) 0;
  833. X    if ((cp = malloc((unsigned) strlen(name) + 1)) == (char *) 0)
  834. X    fatal("No memory for name");
  835. X    strcpy(cp, name);
  836. X    rp->n_name = cp;
  837. X    rp->n_line = (struct line *) 0;
  838. X    rp->n_time = (time_t) 0;
  839. X    rp->n_flag = 0;
  840. X
  841. X    return rp;
  842. X}
  843. X
  844. X/*
  845. X *  Delete the last created name.
  846. X */
  847. X
  848. Xdelname(np)
  849. Xstruct name *np;
  850. X{
  851. X    if (namehead.n_next == np) {
  852. X    namehead.n_next = np->n_next;
  853. X    free(np);
  854. X    }
  855. X}
  856. X
  857. X/*
  858. X *    Add a dependant to the end of the supplied list of dependants.
  859. X *    Return the new head pointer for that list.
  860. X */
  861. Xstruct depend  *
  862. Xnewdep(np, dp)
  863. X    struct name    *np;
  864. X    struct depend  *dp;
  865. X{
  866. X    register struct depend *rp;
  867. X    register struct depend *rrp;
  868. X
  869. X
  870. X    if ((rp = (struct depend *) malloc(sizeof(struct depend)))
  871. X    == (struct depend *) 0)
  872. X    fatal("No memory for dependant");
  873. X    rp->d_next = (struct depend *) 0;
  874. X    rp->d_name = np;
  875. X
  876. X    if (dp == (struct depend *) 0)
  877. X    return rp;
  878. X
  879. X    for (rrp = dp; rrp->d_next; rrp = rrp->d_next);
  880. X
  881. X    rrp->d_next = rp;
  882. X
  883. X    return dp;
  884. X}
  885. X
  886. X
  887. X/*
  888. X *    Add a command to the end of the supplied list of commands.
  889. X *    Return the new head pointer for that list.
  890. X */
  891. Xstruct cmd     *
  892. Xnewcmd(str, cp)
  893. X    char       *str;
  894. X    struct cmd       *cp;
  895. X{
  896. X    register struct cmd *rp;
  897. X    register struct cmd *rrp;
  898. X    register char  *rcp;
  899. X
  900. X
  901. X    if (rcp = rindex(str, '\n'))
  902. X    *rcp = '\0';            /* Loose newline  */
  903. X
  904. X    while (isspace(*str))
  905. X    str++;
  906. X
  907. X    if (*str == '\0')           /* If nothing left, the exit  */
  908. X    return (struct cmd *) 0;
  909. X
  910. X    if ((rp = (struct cmd *) malloc(sizeof(struct cmd)))
  911. X    == (struct cmd *) 0)
  912. X    fatal("No memory for command");
  913. X    rp->c_next = (struct cmd *) 0;
  914. X    if ((rcp = malloc((unsigned) strlen(str) + 1)) == (char *) 0)
  915. X    fatal("No memory for command");
  916. X    strcpy(rcp, str);
  917. X    rp->c_cmd = rcp;
  918. X
  919. X    if (cp == (struct cmd *) 0)
  920. X    return rp;
  921. X
  922. X    for (rrp = cp; rrp->c_next; rrp = rrp->c_next);
  923. X
  924. X    rrp->c_next = rp;
  925. X
  926. X    return cp;
  927. X}
  928. X
  929. X
  930. X/*
  931. X *    Add a new 'line' of stuff to a target.  This check to see
  932. X *    if commands already exist for the target.  If flag is set,
  933. X *    the line is a double colon target.
  934. X *
  935. X *    Kludges:
  936. X *    i)  If the new name begins with a '.', and there are no dependents,
  937. X *        then the target must cease to be a target.    This is for .SUFFIXES.
  938. X *    ii) If the new name begins with a '.', with no dependents and has
  939. X *        commands, then replace the current commands.  This is for
  940. X *        redefining commands for a default rule.
  941. X *    Neither of these free the space used by dependents or commands,
  942. X *    since they could be used by another target.
  943. X */
  944. Xvoid
  945. Xnewline(np, dp, cp, flag)
  946. X    struct name    *np;
  947. X    struct depend  *dp;
  948. X    struct cmd       *cp;
  949. X    bool        flag;
  950. X{
  951. X    bool        hascmds = FALSE;    /* Target has commands    */
  952. X    register struct line *rp;
  953. X    register struct line *rrp;
  954. X
  955. X
  956. X    /* Handle the .SUFFIXES case */
  957. X    if (np->n_name[0] == '.' && !dp && !cp) {
  958. X    for (rp = np->n_line; rp; rp = rrp) {
  959. X        rrp = rp->l_next;
  960. X        free((char *) rp);
  961. X    }
  962. X    np->n_line = (struct line *) 0;
  963. X    np->n_flag &= ~N_TARG;
  964. X    return;
  965. X    }
  966. X    /* This loop must happen since rrp is used later. */
  967. X    for
  968. X    (
  969. X     rp = np->n_line, rrp = (struct line *) 0;
  970. X     rp;
  971. X     rrp = rp, rp = rp->l_next
  972. X    )
  973. X    if (rp->l_cmd)
  974. X        hascmds = TRUE;
  975. X
  976. X    if (hascmds && cp && !(np->n_flag & N_DOUBLE))
  977. X    /* Handle the implicit rules redefinition case */
  978. X    if (np->n_name[0] == '.' && dp == (struct depend *) 0) {
  979. X        np->n_line->l_cmd = cp;
  980. X        return;
  981. X    } else
  982. X        error("Commands defined twice for target %s", np->n_name);
  983. X    if (np->n_flag & N_TARG)
  984. X    if (!(np->n_flag & N_DOUBLE) != !flag)  /* like xor */
  985. X        error("Inconsistent rules for target %s", np->n_name);
  986. X
  987. X    if ((rp = (struct line *) malloc(sizeof(struct line)))
  988. X    == (struct line *) 0)
  989. X    fatal("No memory for line");
  990. X    rp->l_next = (struct line *) 0;
  991. X    rp->l_dep = dp;
  992. X    rp->l_cmd = cp;
  993. X
  994. X    if (rrp)
  995. X    rrp->l_next = rp;
  996. X    else
  997. X    np->n_line = rp;
  998. X
  999. X    np->n_flag |= N_TARG;
  1000. X    if (flag)
  1001. X    np->n_flag |= N_DOUBLE;
  1002. X}
  1003. X
  1004. X
  1005. X/*
  1006. X *    Parse input from the makefile, and construct a tree structure
  1007. X *    of it.
  1008. X */
  1009. Xvoid
  1010. Xinput(fd)
  1011. X    FILE       *fd;
  1012. X{
  1013. X    char       *p;        /* General  */
  1014. X    char       *q;
  1015. X    struct name    *np;
  1016. X    struct depend  *dp;
  1017. X    struct cmd       *cp;
  1018. X    bool        dbl, getline();
  1019. X
  1020. X
  1021. X    if (getline(str1, LZ, fd))      /* Read the first line  */
  1022. X    return;
  1023. X
  1024. X    for (;;) {
  1025. X    if (str1[0] == '\t' || str1[0] == ' ')  /* Rules without targets  */
  1026. X        error("Rules not allowed here");
  1027. X
  1028. X    p = str1;
  1029. X
  1030. X    while (isspace(*p))     /* Find first target  */
  1031. X        p++;
  1032. X
  1033. X    /* -- hu: if = exists in string, hand the string to assign_macro() */
  1034. X    if ((q = index(p, '=')) != NULL) {
  1035. X        assign_macro (p);
  1036. X        if (getline(str1, LZ, fd)) return;
  1037. X        continue;
  1038. X    }
  1039. X
  1040. X    expand(str1);
  1041. X    p = str1;
  1042. X#if 0
  1043. X    while (((q = index(p, ':')) != (char *) 0) &&
  1044. X           (p != q) && (q[-1] == '\\')) {   /* Find dependents  */
  1045. X        register char  *a;
  1046. X
  1047. X        a = q - 1;        /* Del \ chr; move rest back  */
  1048. X        p = q;
  1049. X        while (*a++ = *q++);
  1050. X    }
  1051. X#else
  1052. X    q = index(p, ':');
  1053. X#endif
  1054. X
  1055. X    if (q == (char *) 0)
  1056. X        error("No targets provided");
  1057. X
  1058. X    /* Added by OIS to allow at most one : in target names */
  1059. X
  1060. X    {
  1061. X        register char *a = q;
  1062. X
  1063. X        while (*++a) {
  1064. X        if (*a == ' ' || *a == '\t') {
  1065. X            /* Found no more colons. Must have been first one. */
  1066. X            break;
  1067. X        }
  1068. X        if (*a == ':') {
  1069. X            /* Found second colon. This must be the separator. */
  1070. X            if (a != q+1)   /* No double colon */
  1071. X            q = a;
  1072. X            break;
  1073. X        }
  1074. X        }
  1075. X    }
  1076. X
  1077. X    *q++ = '\0';            /* Separate targets and dependents  */
  1078. X
  1079. X    if (*q == ':') {        /* Double colon */
  1080. X        dbl = 1;
  1081. X        q++;
  1082. X    } else
  1083. X        dbl = 0;
  1084. X
  1085. X    for (dp = (struct depend *) 0; ((p = gettok(&q)) != (char *) 0);)
  1086. X        /* get list of dep's */
  1087. X    {
  1088. X        np = newname(p);    /* Intern name  */
  1089. X        dp = newdep(np, dp);/* Add to dep list */
  1090. X    }
  1091. X
  1092. X    *((q = str1) + strlen(str1) + 1) = '\0';
  1093. X    /* Need two nulls for gettok (Remember separation)  */
  1094. X
  1095. X    cp = (struct cmd *) 0;
  1096. X    if (getline(str2, LZ, fd) == FALSE) {       /* Get commands  */
  1097. X        while (str2[0] == '\t' || str2[0] == ' ') { /*OIS*0.80*/
  1098. X        cp = newcmd(&str2[0], cp);
  1099. X        if (getline(str2, LZ, fd))
  1100. X            break;
  1101. X        }
  1102. X    }
  1103. X    while ((p = gettok(&q)) != (char *) 0) {        /* Get list of targ's */
  1104. X        np = newname(p);    /* Intern name  */
  1105. X        newline(np, dp, cp, dbl);
  1106. X        if (!firstname && p[0] != '.')
  1107. X        firstname = np;
  1108. X    }
  1109. X
  1110. X    if (feof(fd))           /* EOF?  */
  1111. X        return;
  1112. X
  1113. X    strcpy(str1, str2);
  1114. X    }
  1115. X}
  1116. END_OF_FILE
  1117. if test 7073 -ne `wc -c <'input.c'`; then
  1118.     echo shar: \"'input.c'\" unpacked with wrong size!
  1119. fi
  1120. # end of 'input.c'
  1121. fi
  1122. if test -f 'macro.c' -a "${1}" != "-c" ; then 
  1123.   echo shar: Will not clobber existing file \"'macro.c'\"
  1124. else
  1125. echo shar: Extracting \"'macro.c'\" \(2582 characters\)
  1126. sed "s/^X//" >'macro.c' <<'END_OF_FILE'
  1127. X/*
  1128. X *    Macro control for make
  1129. X */
  1130. X
  1131. X
  1132. X#include "h.h"
  1133. X#undef strcmp    /*OIS*0.80*/
  1134. X
  1135. Xstruct macro   *macrohead;
  1136. X
  1137. X
  1138. Xstruct macro   *
  1139. Xgetmp(name)
  1140. X    register char      *name;
  1141. X{
  1142. X    register struct macro *rp;
  1143. X
  1144. X    for (rp = macrohead; rp; rp = rp->m_next)
  1145. X    if (strcmp(name, rp->m_name) == 0)
  1146. X        return rp;
  1147. X    return (struct macro *) 0;
  1148. X}
  1149. X
  1150. X
  1151. Xchar           *
  1152. Xgetmacro(name)
  1153. X    char       *name;
  1154. X{
  1155. X    struct macro   *mp;
  1156. X
  1157. X    if (mp = getmp(name))
  1158. X    return mp->m_val;
  1159. X    else
  1160. X    return "";
  1161. X}
  1162. X
  1163. X
  1164. Xstruct macro   *
  1165. Xsetmacro(name, val)
  1166. X    char       *name;
  1167. X    char       *val;
  1168. X{
  1169. X    register struct macro *rp;
  1170. X    register char  *cp;
  1171. X
  1172. X
  1173. X    /* Replace macro definition if it exists  */
  1174. X    for (rp = macrohead; rp; rp = rp->m_next)
  1175. X    if (strcmp(name, rp->m_name) == 0) {
  1176. X        free(rp->m_val);    /* Free space from old    */
  1177. X        break;
  1178. X    }
  1179. X    if (!rp) {            /* If not defined, allocate space for new  */
  1180. X    if ((rp = (struct macro *) malloc(sizeof(struct macro)))
  1181. X        == (struct macro *) 0)
  1182. X        fatal("No memory for macro");
  1183. X
  1184. X    rp->m_next = macrohead;
  1185. X    macrohead = rp;
  1186. X    rp->m_flag = FALSE;
  1187. X
  1188. X    if ((cp = malloc((unsigned) strlen(name) + 1)) == (char *) 0)
  1189. X        fatal("No memory for macro");
  1190. X    strcpy(cp, name);
  1191. X    rp->m_name = cp;
  1192. X    }
  1193. X    if ((cp = malloc((unsigned) strlen(val) + 1)) == (char *) 0)
  1194. X    fatal("No memory for macro");
  1195. X    strcpy(cp, val);        /* Copy in new value  */
  1196. X    rp->m_val = cp;
  1197. X
  1198. X    return rp;
  1199. X}
  1200. X
  1201. X
  1202. X/*
  1203. X *    Do the dirty work for expand
  1204. X */
  1205. Xvoid
  1206. Xdoexp(to, from, len, buf)
  1207. X    char      **to;
  1208. X    char       *from;
  1209. X    int        *len;
  1210. X    char       *buf;
  1211. X{
  1212. X    register char  *rp;
  1213. X    register char  *p;
  1214. X    register char  *q;
  1215. X    register struct macro *mp;
  1216. X
  1217. X
  1218. X    rp = from;
  1219. X    p = *to;
  1220. X    while (*rp) {
  1221. X    if (*rp != '$') {
  1222. X        *p++ = *rp++;
  1223. X        (*len)--;
  1224. X    } else {
  1225. X        q = buf;
  1226. X        if (*++rp == '{')
  1227. X        while (*++rp && *rp != '}')
  1228. X            *q++ = *rp;
  1229. X        else if (*rp == '(')
  1230. X        while (*++rp && *rp != ')')
  1231. X            *q++ = *rp;
  1232. X        else if (!*rp) {
  1233. X        *p++ = '$';
  1234. X        break;
  1235. X        } else
  1236. X        *q++ = *rp;
  1237. X        *q = '\0';
  1238. X        if (*rp)
  1239. X        rp++;
  1240. X        if (!(mp = getmp(buf)))
  1241. X        mp = setmacro(buf, "");
  1242. X        if (mp->m_flag)
  1243. X        fatal("Infinitely recursive macro %s", mp->m_name);
  1244. X        mp->m_flag = TRUE;
  1245. X        *to = p;
  1246. X        doexp(to, mp->m_val, len, buf);
  1247. X        p = *to;
  1248. X        mp->m_flag = FALSE;
  1249. X    }
  1250. X    if (*len <= 0)
  1251. X        error("Expanded line too long");    /*OIS*0.80*/
  1252. X    }
  1253. X    *p = '\0';
  1254. X    *to = p;
  1255. X}
  1256. X
  1257. X
  1258. X/*
  1259. X *    Expand any macros in str.
  1260. X */
  1261. Xvoid
  1262. Xexpand(str)
  1263. X    char       *str;
  1264. X{
  1265. X    static char     a[LZ];
  1266. X    static char     b[LZ];
  1267. X    char       *p = str;
  1268. X    int         len = LZ - 1;
  1269. X
  1270. X    strcpy(a, str);
  1271. X    doexp(&p, a, &len, b);
  1272. X}
  1273. END_OF_FILE
  1274. if test 2582 -ne `wc -c <'macro.c'`; then
  1275.     echo shar: \"'macro.c'\" unpacked with wrong size!
  1276. fi
  1277. # end of 'macro.c'
  1278. fi
  1279. if test -f 'main.c' -a "${1}" != "-c" ; then 
  1280.   echo shar: Will not clobber existing file \"'main.c'\"
  1281. else
  1282. echo shar: Extracting \"'main.c'\" \(6566 characters\)
  1283. sed "s/^X//" >'main.c' <<'END_OF_FILE'
  1284. X/*
  1285. X *    make [-f makefile] [-ins] [target(s) ...]
  1286. X *
  1287. X *    (Better than EON mk but not quite as good as UNIX make)
  1288. X *
  1289. X *    -f makefile name
  1290. X *    -i ignore exit status
  1291. X *    -n Pretend to make
  1292. X *    -p Print all macros & targets
  1293. X *    -q Question up-to-dateness of target.  Return exit status 1 if not
  1294. X *    -r Don't not use inbuilt rules
  1295. X *    -s Make silently
  1296. X *    -t Touch files instead of making them
  1297. X *    -m Change memory requirements (EON only)
  1298. X */
  1299. X
  1300. X#include <stdio.h>
  1301. X#include "h.h"
  1302. X
  1303. X#ifdef unix
  1304. X#include <sys/errno.h>
  1305. X#endif
  1306. X#ifdef eon
  1307. X#include <sys/err.h>
  1308. X#endif
  1309. X#ifdef os9
  1310. X#include <errno.h>
  1311. X#endif
  1312. X#ifdef amiga
  1313. X#include <errno.h>
  1314. X#endif
  1315. X
  1316. X#ifdef eon
  1317. X#define MEMSPACE    (16384)
  1318. X#endif
  1319. X
  1320. X
  1321. Xchar           *myname;
  1322. Xchar           *makefile;    /* The make file  */
  1323. X#ifdef eon
  1324. Xunsigned    memspace = MEMSPACE;
  1325. X#endif
  1326. X
  1327. XFILE           *ifd;        /* Input file desciptor  */
  1328. Xbool        domake = TRUE;    /* Go through the motions option  */
  1329. Xbool        ignore = FALSE; /* Ignore exit status option  */
  1330. Xbool        silent = FALSE; /* Silent option  */
  1331. Xbool        print = FALSE;    /* Print debuging information  */
  1332. Xbool        rules = TRUE;    /* Use inbuilt rules  */
  1333. Xbool        dotouch = FALSE;/* Touch files instead of making  */
  1334. Xbool        quest = FALSE;    /* Question up-to-dateness of file  */
  1335. X
  1336. X
  1337. Xvoid
  1338. Xmain(argc, argv)
  1339. X    register int    argc;
  1340. X    register char **argv;
  1341. X{
  1342. X    register char  *p;        /* For argument processing  */
  1343. X    int         estat = 0;    /* For question  */
  1344. X    register struct name *np;
  1345. X    void        prt(), circh();
  1346. X
  1347. X    myname = (argc-- < 1) ? "make" : *argv++;
  1348. X
  1349. X    while ((argc > 0) && (**argv == '-')) {
  1350. X    argc--;         /* One less to process    */
  1351. X    p = *argv++;        /* Now processing this one  */
  1352. X
  1353. X    while (*++p != '\0') {
  1354. X        switch (*p) {
  1355. X        case 'f':           /* Alternate file name  */
  1356. X        if (*++p == '\0') {
  1357. X            if (argc-- <= 0)
  1358. X            usage();
  1359. X            p = *argv++;
  1360. X        }
  1361. X        makefile = p;
  1362. X        goto end_of_args;
  1363. X#ifdef eon
  1364. X        case 'm':           /* Change space requirements  */
  1365. X        if (*++p == '\0') {
  1366. X            if (argc-- <= 0)
  1367. X            usage();
  1368. X            p = *argv++;
  1369. X        }
  1370. X        memspace = atoi(p);
  1371. X        goto end_of_args;
  1372. X#endif
  1373. X        case 'n':           /* Pretend mode  */
  1374. X        domake = FALSE;
  1375. X        break;
  1376. X        case 'i':           /* Ignore fault mode  */
  1377. X        ignore = TRUE;
  1378. X        break;
  1379. X        case 's':           /* Silent about commands  */
  1380. X        silent = TRUE;
  1381. X        break;
  1382. X        case 'p':
  1383. X        print = TRUE;
  1384. X        break;
  1385. X        case 'r':
  1386. X        rules = FALSE;
  1387. X        break;
  1388. X        case 't':
  1389. X        dotouch = TRUE;
  1390. X        break;
  1391. X        case 'q':
  1392. X        quest = TRUE;
  1393. X        break;
  1394. X        default:        /* Wrong option  */
  1395. X        usage();
  1396. X        }
  1397. X    }
  1398. Xend_of_args:;
  1399. X    }
  1400. X
  1401. X#ifdef amiga
  1402. X    if ((ifd = fopen("s:builtins.make", "r")) != (FILE *) 0) {
  1403. X    input(ifd);
  1404. X    fclose(ifd);
  1405. X    } else
  1406. X#endif
  1407. X    makerules();
  1408. X
  1409. X#ifdef eon
  1410. X    if (initalloc(memspace) == 0xffff)    /* Must get memory for alloc  */
  1411. X    fatal("Cannot initalloc memory");
  1412. X#endif
  1413. X
  1414. X    if (! makefile) {    /* If no file, then use default */
  1415. X    if ((ifd = fopen(DEFN1, "r")) == (FILE *) 0)
  1416. X#ifdef eon
  1417. X        if (errno != ER_NOTF)
  1418. X        fatal("Can't open %s; error %02x", DEFN1, errno);
  1419. X#endif
  1420. X#ifdef unix
  1421. X    if (errno != ENOENT)
  1422. X        fatal("Can't open %s; error %02x", DEFN1, errno);
  1423. X#endif
  1424. X#ifdef amiga
  1425. X    if (errno != ENOENT)
  1426. X        fatal("Can't open %s; error %02x", DEFN1, errno);
  1427. X#endif
  1428. X#ifdef DEFN2
  1429. X    if ((ifd == (FILE *) 0)
  1430. X        && ((ifd = fopen(DEFN2, "r")) == (FILE *) 0))
  1431. X        fatal("Can't open %s", DEFN2);
  1432. X#else
  1433. X    /* -- hu: do nothing so we may process command line later */
  1434. X#endif
  1435. X    } else if (strcmp(makefile, "-") == 0)      /* Can use stdin as makefile  */
  1436. X    ifd = stdin;
  1437. X    else if ((ifd = fopen(makefile, "r")) == (FILE *) 0)
  1438. X    ; /* -- hu: again, no makefile is fine here */
  1439. X
  1440. X    /* -- hu: if valid makefile exists, read it in now */
  1441. X    if (ifd != (FILE *)0) {
  1442. X    input(ifd);         /* Input all the gunga    */
  1443. X    fclose(ifd);        /* Finished with makefile  */
  1444. X    }
  1445. X    lineno = 0;         /* Any calls to error now print no line
  1446. X                 * number */
  1447. X
  1448. X    setmacro ("$", "$");
  1449. X
  1450. X    /* -- hu: overwrite/add command line macro assignments */
  1451. X    while (argc  &&  (p = index(*argv, '='))) {
  1452. X    assign_macro(*argv);
  1453. X    argv++;
  1454. X    argc--;
  1455. X    }
  1456. X
  1457. X    if (print)
  1458. X    prt();            /* Print out structures  */
  1459. X
  1460. X    np = newname(".SILENT");
  1461. X    if (np->n_flag & N_TARG)
  1462. X    silent = TRUE;
  1463. X
  1464. X    np = newname(".IGNORE");
  1465. X    if (np->n_flag & N_TARG)
  1466. X    ignore = TRUE;
  1467. X
  1468. X    precious();
  1469. X
  1470. X    /* Check circles in target definitions */
  1471. X    if (! firstname) circh();
  1472. X
  1473. X    /* -- hu: no command line arg, if target defined from makefile, do it */
  1474. X    if (argc == 0) {
  1475. X      if (! firstname) estat = make(firstname, 0);
  1476. X    }
  1477. X    else /* treat command line args as targets to make */
  1478. X    while (argc--) {
  1479. X        if (!print && !silent && strcmp(*argv, "love") == 0) {
  1480. X          if (strcmp(myname, "make") == 0) /* -- hu: humor them */
  1481. X        printf("With me?\n");
  1482. X          else printf("Not War!\n");
  1483. X        }
  1484. X        else estat |= make(newname(*argv++), 0);
  1485. X    }
  1486. X
  1487. X    if (quest) exit (estat);
  1488. X    else exit (0);
  1489. X}
  1490. X
  1491. X
  1492. Xusage()
  1493. X{
  1494. X    fprintf(stderr,
  1495. X"Usage: %s [-f makefile] [-inpqrst] [macro=val ...] [target(s) ...]\n", myname);
  1496. X    fprintf(stderr,"\n");
  1497. X    fprintf(stderr,"  -f file  Use `file' instead of `M/makefile'\n");
  1498. X    fprintf(stderr,"  -i  Ignore invoked command errors (continue regardless)\n");
  1499. X    fprintf(stderr,"  -n  No make (just print actions to be taken)\n");
  1500. X    fprintf(stderr,"  -p  Print all macros & targets\n");
  1501. X    fprintf(stderr,"  -q  Check if target is up-to-date.  Exit 1 if not\n");
  1502. X    fprintf(stderr,"  -r  Don't use built-in rules\n");
  1503. X    fprintf(stderr,"  -s  Make silently\n");
  1504. X    fprintf(stderr,"  -t  Touch needed files instead of making them\n");
  1505. X#ifdef eon
  1506. X    fprintf(stderr,"  -m  Change memory requirements (EON only)\n");
  1507. X#endif
  1508. X    exit(1);
  1509. X}
  1510. X
  1511. X
  1512. Xvoid
  1513. Xfatal(msg, a1, a2, a3, a4, a5, a6)
  1514. X    char       *msg;
  1515. X{
  1516. X    fprintf(stderr, "%s: ", myname);
  1517. X    fprintf(stderr, msg, a1, a2, a3, a4, a5, a6);
  1518. X    fputc('\n', stderr);
  1519. X    exit(1);
  1520. X}
  1521. X
  1522. X#ifdef amiga    /*OIS*0.80*/
  1523. X
  1524. X/*
  1525. X * The Amiga case-insensitive filing system needs a case-insensitive
  1526. X * filename comparison. Since strcmp() in this make is only applied to
  1527. X * filenames, we simply replace it.
  1528. X * Unfortunately, this also affects .PRECIOUS, .IGNORE, .SUFFIXES and
  1529. X * .SILENT. Therefore, we need a hack, but that costs space, so we don't.
  1530. X */
  1531. X
  1532. Xint lower(c)
  1533. Xregister unsigned int c;
  1534. X{
  1535. X    if (c >= 'A' && c <= 'Z')
  1536. X    return c - 'A' + 'a';
  1537. X
  1538. X    return c;
  1539. X}
  1540. X
  1541. Xint stricmp(first, second)    /* Case-insensitive strcmp() */
  1542. Xregister unsigned char *first, *second;
  1543. X{
  1544. X    register int cmp;
  1545. X
  1546. X    while (!(cmp = lower(*first++) - lower(*second++))) {
  1547. X    if (!first[-1]) return 0;
  1548. X    }
  1549. X
  1550. X    return (cmp < 0) ? -1 : 1;
  1551. X}
  1552. X
  1553. X/* Manx and PDC allow you to leave out Workbench code */
  1554. X
  1555. X_wb_parse(){}
  1556. X
  1557. X#endif
  1558. END_OF_FILE
  1559. if test 6566 -ne `wc -c <'main.c'`; then
  1560.     echo shar: \"'main.c'\" unpacked with wrong size!
  1561. fi
  1562. # end of 'main.c'
  1563. fi
  1564. if test -f 'make.n' -a "${1}" != "-c" ; then 
  1565.   echo shar: Will not clobber existing file \"'make.n'\"
  1566. else
  1567. echo shar: Extracting \"'make.n'\" \(7344 characters\)
  1568. sed "s/^X//" >'make.n' <<'END_OF_FILE'
  1569. X.so an
  1570. X.de HP
  1571. X.ti -5
  1572. X.en
  1573. X.TH MAKE 1 "AMIGA Programmer's Manual"
  1574. X.SH NAME
  1575. Xmake - maintain program groups
  1576. X.SH SYNTAX
  1577. Xmake [ -f makefile ] [ option ] ... file ...
  1578. X.SH DESCRIPTION
  1579. X.I Make
  1580. Xexecutes commands in
  1581. X.I makefile
  1582. Xto update one or more target
  1583. X.I names. Name
  1584. Xis typically a program. If no -f option
  1585. Xis present, `makefile' and `Makefile' are tried in order.
  1586. XIf
  1587. X.I makefile
  1588. Xis `-', the standard input is taken. More than one -f option may appear.
  1589. X
  1590. X.I Make
  1591. Xupdates a target if it depends on prerequisite files that have been
  1592. Xmodified since the target was last modified, or if the target does not
  1593. Xexist.
  1594. X
  1595. X.I Makefile
  1596. Xcontains a sequence of entries that specify dependencies. The first line of
  1597. Xan entry is a blank-separated list of targets, then a colon, then a list of
  1598. Xprerequisite files. Text following a semicolon, and all following lines
  1599. Xthat begin with a tab, are shell commands to be executed to update the
  1600. Xtarget. If a name appears on the left of more than one `colon' line, then
  1601. Xit depends on all of the names on the right of the colon on those lines,
  1602. Xbut only one command sequence may be specified for it. If a name appears on
  1603. Xa line with a double colon :: then the command sequence following that line
  1604. Xis performed only if the name is out of date with respect to the names to
  1605. Xthe right of the double colon, and is not affected by other double colon
  1606. Xlines on which that name may appear.
  1607. X
  1608. XTwo special forms of a name are recognized. A name like
  1609. X.I a(b)
  1610. Xmeans the file named
  1611. X.I b
  1612. Xstored in the archive named
  1613. X.I a.
  1614. XA name like
  1615. X.I a((b))
  1616. Xmeans the file stored in archive a containing the entry point
  1617. X.I b.
  1618. X
  1619. XSharp and newline surround comments.
  1620. X
  1621. XThe following makefile says that `pgm' depends on two files `a.o' and
  1622. X`b.o', and that they in turn depend on `.c' files and a common file `incl'.
  1623. X
  1624. X        pgm: a.o b.o
  1625. X                cc a.o b.o -lm -o pgm
  1626. X        a.o: incl a.c
  1627. X                cc -c a.c
  1628. X        b.o: incl b.c
  1629. X                cc -c b.c
  1630. X
  1631. X.I Makefile
  1632. Xentries of the form
  1633. X
  1634. X        string1 = string2
  1635. X
  1636. Xare macro definitions. Subsequent appearances of
  1637. X.I $(string1)
  1638. Xor
  1639. X.I ${string1}
  1640. Xare replaced by
  1641. X.I string2.
  1642. XIf
  1643. X.I string1
  1644. Xis a single character, the parentheses or braces are optional.
  1645. X
  1646. X.I Make
  1647. Xinfers prerequisites for files for which
  1648. X.I makefile
  1649. Xgives no construction commands. For example, a `.c' file may be inferred as
  1650. Xprerequisite for a `.o' file and be compiled to produce the `.o' file. Thus
  1651. Xthe preceding example can be done more briefly:
  1652. X
  1653. X        pgm: a.o b.o
  1654. X                cc a.o b.o -lm -o pgm
  1655. X        a.o b.o: incl
  1656. X
  1657. XPrerequisites are inferred according to selected suffixes listed as the
  1658. X`prerequisites' for the special name `.SUFFIXES'; multiple lists
  1659. Xaccumulate; an empty list clears what came before. Order is significant;
  1660. Xthe first possible name for which both a file and a rule as described in
  1661. Xthe next paragraph exist is inferred. The default list is
  1662. X
  1663. X        .SUFFIXES: .out .o .c .e .r .f .y .l .s .p
  1664. X
  1665. XThe rule to create a file with suffix
  1666. X.I s2
  1667. Xthat depends on a similarly named file with suffix
  1668. X.I s1
  1669. Xis specified as an entry for the `target'
  1670. X.I s1s2.
  1671. XIn such an entry, the special macro $* stands for the target name with
  1672. Xsuffix deleted, $@@ for the full target name, $< for the complete list of
  1673. Xprerequisites, and $? for the list of prerequisites that are out of date.
  1674. XFor example, a rule for making optimized `.o' files from `.c' files is
  1675. X
  1676. X        .c.o: ; cc -c -O -o $@@ $*.c
  1677. X
  1678. XCertain macros are used by the default inference rules to communicate
  1679. Xoptional arguments to any resulting compilations. In particular, `CFLAGS'
  1680. Xis used for
  1681. X.I cc(1)
  1682. Xoptions, `FFLAGS' for
  1683. X.I f77(1)
  1684. Xoptions, `PFLAGS' for
  1685. X.I pc(1)
  1686. Xoptions, and `LFLAGS' and `YFLAGS' for
  1687. X.I lex
  1688. Xand
  1689. X.I yacc(1)
  1690. Xoptions. In addition, the macro `MFLAGS' is filled in with the initial
  1691. Xcommand line options supplied to
  1692. X.I make.
  1693. XThis simplifies maintaining a hierarchy of makefiles as one may then invoke
  1694. X.I make
  1695. Xon makefiles in subdirectories and pass along useful options such as -k.
  1696. X
  1697. XCommand lines are executed one at a time, each by its own shell. A line is
  1698. Xprinted when it is executed unless the special target `.SILENT' is in
  1699. X.I makefile,
  1700. Xor the first character of the command is `@@'.
  1701. X
  1702. XCommands returning nonzero status (see
  1703. X.I intro(1))
  1704. Xcause
  1705. X.I make
  1706. Xto terminate unless the special target `.IGNORE' is in
  1707. X.I makefile
  1708. Xor the command begins with <tab><hyphen>.
  1709. X
  1710. XInterrupt and quit cause the target to be deleted unless the target is a
  1711. Xdirectory or depends on the special name `.PRECIOUS'.
  1712. X
  1713. XOther options:
  1714. X
  1715. X.RS +5
  1716. X.HP
  1717. X-i@tEquivalent to the special entry `.IGNORE:'.
  1718. X
  1719. X.HP
  1720. X-k@tWhen a command returns nonzero status, abandon work on the current
  1721. Xentry, but continue on branches that do not depend on the current entry.
  1722. X
  1723. X.HP
  1724. X-n@tTrace and print, but do not execute the commands needed to update the
  1725. Xtargets.
  1726. X
  1727. X.HP
  1728. X-t@tTouch, i.e. update the modified date of targets, without executing any
  1729. Xcommands.
  1730. X
  1731. X.HP
  1732. X-r@tEquivalent to an initial special entry `.SUFFIXES:' with no list.
  1733. X
  1734. X.HP
  1735. X-s@tEquivalent to the special entry `.SILENT:'.
  1736. X
  1737. X.HP
  1738. X-q@tQuestion up-to-dateness of target. Return exit status 1 if not;
  1739. Xotherwise, return 0.
  1740. X
  1741. X.HP
  1742. X-r@tDon't use built-in rules.
  1743. X.RE
  1744. X.SH FILES
  1745. Xmakefile, Makefile
  1746. X.SH "SEE ALSO"
  1747. Xsh(1), touch(1), f77(1), pc(1)
  1748. X.br
  1749. XS. I. Feldman
  1750. X.I "Make - A Program for Maintaining Computer Programs"
  1751. X.SH BUGS
  1752. XSome commands return nonzero status inappropriately. Use -i
  1753. Xto overcome the difficulty.
  1754. XCommands that are directly executed by the shell, notably
  1755. X.I cd(1),
  1756. Xare ineffectual across newlines in
  1757. X.I make.
  1758. X.SH "AMIGA VERSION"
  1759. XNot all of the above applies to the Amiga version of
  1760. X.I make.
  1761. XIn particular, the default rules and suffixes are different.
  1762. X
  1763. XOmissions:
  1764. X.br
  1765. XLibraries and the related notation are not implemented.
  1766. X.br
  1767. XThe -k option is not supported.
  1768. X.br
  1769. XThe `;' construct is not implemented.
  1770. X.br
  1771. XThe remarks related to
  1772. X.I MFLAGS, lex(1), yacc(1), f77(1)
  1773. Xand
  1774. X.I pc(1)
  1775. Xdo not apply.
  1776. X.br
  1777. X$< and $? are not exactly as specified: $< is ONE prerequisite that is out
  1778. Xof date (including path name), and $? is ALL prerequisites (without path
  1779. Xnames).
  1780. X
  1781. XAdditions:
  1782. X.br
  1783. XIf a file
  1784. X.I s:builtins.make
  1785. Xexists, this file is used instead of the built-in rules.
  1786. X.br
  1787. XFilenames are not case-significant. Unfortunately, this also applies to the
  1788. Xspecial target names .PRECIOUS, .IGNORE and .SILENT. These can also be
  1789. Xspecified as .Precious, or .iGnOrE.
  1790. X.br
  1791. X.I Cd
  1792. Xcommands are effective.
  1793. X.br
  1794. XComment characters (#) may be escaped with a backslash (\).
  1795. X.br
  1796. XAt most 1 colon is allowed in a target file name (for including device
  1797. Xnames). In that case, the trailing colon must follow the target name
  1798. Ximmediately, without any intervening white space. Spaces in the names are
  1799. Xnot allowed.
  1800. X.br
  1801. XA new special target name has been added:
  1802. X.it "@.PATH.
  1803. XAny prerequisite names for
  1804. X.it "@.PATH
  1805. Xare used for finding source files for implicit rules. You name one or more
  1806. Xdirectories, and if the source file for an implicit rule cannot be found
  1807. Xin the current directory, each of the the given pathnames is prepended (in
  1808. Xthe order given) to the source name, until the file is found.
  1809. X
  1810. XFor instance, the Makefile
  1811. X
  1812. X        .PATH:  src/ include/ src/old
  1813. X
  1814. X        pgm:    pgm.o
  1815. X
  1816. Xwill look (according to the .c.o rule) for pgm.c, src/pgm.c, include/pgm.c
  1817. Xand src/oldpgm.c, in that order. Of course, due to other implicit rules,
  1818. Xother files (with other suffixes) may be tried as well.
  1819. END_OF_FILE
  1820. if test 7344 -ne `wc -c <'make.n'`; then
  1821.     echo shar: \"'make.n'\" unpacked with wrong size!
  1822. fi
  1823. # end of 'make.n'
  1824. fi
  1825. if test -f 'makefile' -a "${1}" != "-c" ; then 
  1826.   echo shar: Will not clobber existing file \"'makefile'\"
  1827. else
  1828. echo shar: Extracting \"'makefile'\" \(580 characters\)
  1829. sed "s/^X//" >'makefile' <<'END_OF_FILE'
  1830. X# Makefile for PDmake (to use MANX 3.6a compiler/linker)
  1831. X#
  1832. X# +L so integers are 32-bit long.
  1833. X#
  1834. X# (I wish people who release makefiles will pick this up as a habit: note
  1835. X#  what your various option flags mean, so that those who don't use the same
  1836. X#  compiler as you can still understand what is happening. -huver)
  1837. X
  1838. XCFLAGS=+L -Damiga -Dmanx #-Dpdc
  1839. XCC=cc
  1840. X
  1841. XOBJS = main.o make.o rules.o reader.o        \    
  1842. X  # comment embeded in continuation
  1843. X       input.o macro.o assign_macro.o check.o
  1844. X
  1845. Xm:    $(OBJS)
  1846. X    ln -o m $(OBJS) -lc
  1847. X
  1848. Xclean:    $(OBJS)
  1849. X    delete $(OBJS)
  1850. X
  1851. Xman:    make.n an
  1852. X    nro >make.man make.n
  1853. END_OF_FILE
  1854. if test 580 -ne `wc -c <'makefile'`; then
  1855.     echo shar: \"'makefile'\" unpacked with wrong size!
  1856. fi
  1857. # end of 'makefile'
  1858. fi
  1859. if test -f 'reader.c' -a "${1}" != "-c" ; then 
  1860.   echo shar: Will not clobber existing file \"'reader.c'\"
  1861. else
  1862. echo shar: Extracting \"'reader.c'\" \(2516 characters\)
  1863. sed "s/^X//" >'reader.c' <<'END_OF_FILE'
  1864. X/*
  1865. X *    Read in makefile
  1866. X */
  1867. X
  1868. X
  1869. X#include <stdio.h>
  1870. X#include <ctype.h>
  1871. X#include "h.h"
  1872. X
  1873. X
  1874. Xint        lineno;
  1875. X
  1876. X
  1877. X/*
  1878. X *    Syntax error handler.  Print message, with line number, and exits.
  1879. X */
  1880. Xvoid
  1881. Xerror(msg, a1, a2, a3)
  1882. X    char       *msg;
  1883. X{
  1884. X    fprintf(stderr, "%s: ", myname);
  1885. X    fprintf(stderr, msg, a1, a2, a3);
  1886. X    if (lineno)
  1887. X    fprintf(stderr, " near line %d", lineno);
  1888. X    fputc('\n', stderr);
  1889. X    exit(1);
  1890. X}
  1891. X
  1892. X
  1893. X/*
  1894. X *    Read a line into the supplied buffer of length 'size'.  Remove
  1895. X *    comments, ignore blank lines. Deal with quoted (\) #, and
  1896. X *    quoted newlines.  If EOF return TRUE.
  1897. X *
  1898. X * -hu: "Deal with quoted #"?  What the bloody heck is that?  '#' is a
  1899. X *      comment introducer, from it to end-of-line should be ignored.
  1900. X */
  1901. Xbool
  1902. Xgetline (str, size, fd)
  1903. Xchar *str;
  1904. Xint  size;
  1905. XFILE  *fd;
  1906. X{
  1907. X    register char  *p;
  1908. X    register char  *q;        /*OIS*0.80*/
  1909. X    register char  *buf;
  1910. X    int         pos = 0;
  1911. X
  1912. X    size--;    /* disccount one byte for null terminator */
  1913. X
  1914. X    for (;;) {
  1915. X
  1916. X    if ((size - pos) <= 0) error ("Line too long");
  1917. X    buf = str + pos;
  1918. X    if (fgets(buf, size - pos, fd) == NULL)
  1919. X        return TRUE;    /* EOF    */
  1920. X
  1921. X    lineno++;
  1922. X    if ((p = index(buf, '\n')) == NULL) error("Line too long");
  1923. X
  1924. X    /* strip out comment */
  1925. X    if ((p = index(buf, '#')) != NULL) {
  1926. X      if (p == buf) continue;
  1927. X      *p = '\0';
  1928. X    }
  1929. X
  1930. X    /* empty line ? */
  1931. X    for (p = buf; isspace(*p); p++);
  1932. X    if (*p == '\0') continue;
  1933. X
  1934. X    /* compress leading spaces from continued line(s) */
  1935. X    if (pos  &&  p != buf)
  1936. X      for (q = buf; (*q = *p) != '\0'; q++, p++);
  1937. X      
  1938. X    /* look at last char */
  1939. X    p = buf + strlen(buf) - 1;
  1940. X
  1941. X    /* skip trailing white spaces -- we know now the line isn't empty */
  1942. X    while ( isspace (*p)) p--;
  1943. X
  1944. X    /* backslash continuation? */
  1945. X    if (*p == '\\') {
  1946. X      /* compress whitespaces before \ char */
  1947. X      p--;
  1948. X      while (isspace(*p)) p--;
  1949. X      *++p = ' ';        /* replace with single space */
  1950. X      pos = (++p) - str;    /* go read more */
  1951. X      continue;
  1952. X    }
  1953. X    *++p = '\n';
  1954. X    return FALSE;    /* a valid line is read in */
  1955. X    }
  1956. X}
  1957. X
  1958. X
  1959. X/*
  1960. X *    Get a word from the current line, surounded by white space.
  1961. X *    return a pointer to it. String returned has no white spaces
  1962. X *    in it.
  1963. X */
  1964. Xchar           *
  1965. Xgettok(ptr)
  1966. X    register char  **ptr;    /*OIS*0.80*/
  1967. X{
  1968. X    register char  *p;
  1969. X
  1970. X
  1971. X    while (isspace(**ptr))    /* Skip spaces    */
  1972. X    (*ptr)++;
  1973. X
  1974. X    if (**ptr == '\0')          /* Nothing after spaces  */
  1975. X    return NULL;
  1976. X
  1977. X    p = *ptr;            /* word starts here  */
  1978. X
  1979. X    while ((**ptr != '\0') && (!isspace(**ptr)))
  1980. X    (*ptr)++;        /* Find end of word  */
  1981. X
  1982. X    *(*ptr)++ = '\0';           /* Terminate it  */
  1983. X
  1984. X    return (p);
  1985. X}
  1986. END_OF_FILE
  1987. if test 2516 -ne `wc -c <'reader.c'`; then
  1988.     echo shar: \"'reader.c'\" unpacked with wrong size!
  1989. fi
  1990. # end of 'reader.c'
  1991. fi
  1992. echo shar: End of archive 1 \(of 2\).
  1993. cp /dev/null ark1isdone
  1994. MISSING=""
  1995. for I in 1 2 ; do
  1996.     if test ! -f ark${I}isdone ; then
  1997.     MISSING="${MISSING} ${I}"
  1998.     fi
  1999. done
  2000. if test "${MISSING}" = "" ; then
  2001.     echo You have unpacked both archives.
  2002.     rm -f ark[1-9]isdone
  2003. else
  2004.     echo You still need to unpack the following archives:
  2005.     echo "        " ${MISSING}
  2006. fi
  2007. ##  End of shell archive.
  2008. exit 0
  2009. -- 
  2010. Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
  2011. Mail comments to the moderator at <amiga-request@cs.odu.edu>.
  2012. Post requests for sources, and general discussion to comp.sys.amiga.
  2013.